package com.health.central_authentication.filter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.health.result.CodeStatus;
import com.health.result.ResultUtils;
import com.health.security.CentralAuthenticationToken;
import com.health.security.Student;
import com.health.security.StudentService;
import com.health.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.regex.Pattern;

/**
 * 自定义token、验证码过滤器
 * @author: zipeng Li
 * 2021/6/13  15:25
 */
@Slf4j
@Component
public class DGUTCheckTokenFilter extends OncePerRequestFilter {
    @Autowired
    private StudentService studentService;
    @Autowired
    private JwtUtils jwtUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String url = request.getRequestURI();
        log.info(url);
        boolean matches = Pattern.compile("/api/user/.*").matcher(url).matches();
        if(!matches){
            filterChain.doFilter(request, response);
            return;
        } else{
            //验证token
            boolean b = validateToken(request, response);
            if(!b){
                return;
            }
            // 放行请求
            filterChain.doFilter(request, response);
        }
    }

    //验证token
    private boolean validateToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/javascript;charset=utf-8");
        //获取前端传来的token
        String token = request.getHeader("token");
        //解析token，获取用户
        String username = jwtUtils.getStudentIdFromToken(token);
        //如果token或者student为空的话，不能通过认证
        if(StringUtils.isBlank(token) || username == null){
            response.getWriter().print(new ObjectMapper().writeValueAsString(ResultUtils.error("token失效", CodeStatus.TOKEN_ERROR)));
            return false;
        }
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Student::getUsername, username);
        Student one = studentService.getOne(wrapper);
        if(one == null){
            response.getWriter().print(new ObjectMapper().writeValueAsString(ResultUtils.error("token失效", CodeStatus.TOKEN_ERROR)));
            return false;
        }
        CentralAuthenticationToken authenticationToken = new CentralAuthenticationToken(one, AuthorityUtils.createAuthorityList("USER"));
        //设置为已登录
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        return true;
    }
}

